/**
 * An abstract element that can be extended with namespaced child elements
 */
public interface ExtensibleElement extends Element {

  /**
   * Returns the complete set of extension elements
   * @return a listing of extensions
   */
  List<Element> getExtensions();
  
  /**
   * Returns the complete set of extension elements using the specified 
   * XML Namespace URI
   * @param uri A namespace URI
   * @return A listing of extensions using the specified XML namespace 
   */
  List<Element> getExtensions(String uri);
  
  /**
   * Returns the complete set of extension elements using the specified
   * XML qualified name
   * @param qname An XML QName
   * @return A listing of extensions with the specified QName
   */
  List<Element> getExtensions(XML.QName qname);
  
  /**
   * Returns the first extension element with the XML qualified name
   * @param qname An XML QName
   * @return An extension with the specified qname
   */
  Element getExtension(QName qname);
  
  /**
   * Adds an individual extension element
   * @param extension An extension element to add
   */
  ExtensibleElement>T addExtension(Element extension);

  /**
   * Adds an individual extension element before the specified element 
   */
  ExtensibleElement addExtension(Element extension, Element b4);
  
  /**
   * Adds an individual extension element
   * @param qname An extension element to create
   * @return The newly created extension element
   */
  Element addExtension(XML.QName qname);
  
  /**
   * Adds an individual extension element
   * @param qname An extension element to create
   * @return The newly created extension element
   */
  Element addExtension(XML.QName qname, XML.QName b4);
  
  /**
   * Adds an individual extension element
   * @param namespace An XML namespace
   * @param localPart A localname
   * @param prefix A XML namespace prefix
   * @return The newly creatd extension element
   */
  Element addExtension(
    String namespace, 
    String localPart,
    String prefix);
  
  /**
   * Adds a simple extension (text content only)
   * @param qname An XML QName
   * @param value The simple text value of the element
   * @return The newly created extension element
   */
  Element addSimpleExtension(
    XML.QName qname, 
    String value);
  
  /**
   * Adds a simple extension (text content only)
   * @param namespace An XML namespace
   * @param localPart A local name
   * @param prefix A namespace prefix
   * @param value The simple text value
   * @return The newly created extension element
   */
  Element addSimpleExtension(
    String namespace, 
    String localPart, 
    String prefix, 
    String value);
  
  /**
   * Gets the value of a simple extension
   * @param qname An XML QName
   * @return The string value of the extension
   */
  String getSimpleExtension(XML.QName qname);
  
  /**
   * Gets the value of a simple extension
   * @param namespace An XML namespace
   * @param localPart A localname
   * @param prefix A namespace prefix
   * @return The string value of the extension
   */
  String getSimpleExtension(String namespace, String localPart, String prefix);
  
  /**
   * Find an extension by Class rather than QName
   * @param _class The implementation class of the extension
   * @return The extension element
   */
  Element getExtension(String _class);
}
